package com.ds.home.proxy;

import com.alibaba.fastjson.annotation.JSONField;
import com.ds.home.EIDevice;
import com.ds.home.engine.AppEngine;
import com.ds.home.engine.GWEngine;
import com.ds.iot.*;
import com.ds.iot.enums.DeviceStatus;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class DeviceProxy implements Device {

    private String deviceId;

    private String systemCode;


    public DeviceProxy(String deviceId, String systemCode) {
        this.deviceId = deviceId;
        this.systemCode = systemCode;

    }

    public Long getAddtime() {
        return getDbDevice().getAddtime();
    }

    public String getAppaccount() {
        return getDbDevice().getAppaccount();
    }

    public String getBatch() {
        return getDbDevice().getBatch();
    }

    public String getBattery() {
        return getDbDevice().getBattery();
    }

    public String getBindingaccount() {
        return getDbDevice().getBindingaccount();
    }

    public String getChannel() {
        return getDbDevice().getChannel();
    }

    public String getDeviceid() {
        return getDbDevice().getDeviceid();
    }


    public void setDeviceid(String deviceid) {

        this.deviceId = deviceid;
    }

    public Integer getDevicetype() {

        Integer sensorType = getDbDevice().getDevicetype();

        if (sensorType == null || sensorType == 100) {
            if (this.getDeviceEndPoints() != null && this.getDeviceEndPoints().size() > 0) {
                sensorType = this.getDeviceEndPoints().get(0).getSensortype().getType();
            }
        }


        return sensorType;
    }

    public String getFactory() {
        return getDbDevice().getFactory();
    }

    public String getMacaddress() {
        return getDbDevice().getMacaddress();
    }

    public String getName() {
        return getDbDevice().getName();
    }

    public String getSerialno() {
        return getDbDevice().getSerialno();
    }


    public DeviceStatus getStates() {

        return DeviceStatus.fromCode(getDbDevice().getStates());
    }

    public String getSubsyscode() {
        return getDbDevice().getSubsyscode();
    }

    public void setAddtime(Long addtime) {
        getDbDevice().setAddtime(addtime);
    }

    public void setAppaccount(String appaccount) {

        getDbDevice().setAppaccount(appaccount);
    }


    public void setBatch(String batch) {
        getDbDevice().setBatch(batch);
    }

    public void setBattery(String battery) {
        getDbDevice().setBattery(battery);
    }

    public void setBindingaccount(String bindingaccount) {
        getDbDevice().setBindingaccount(bindingaccount);
    }

    public void setChannel(String channel) {
        getDbDevice().setChannel(channel);
    }

    public void setDevicetype(Integer devicetype) {
        getDbDevice().setDevicetype(devicetype);
    }

    public void setFactory(String factory) {
        getDbDevice().setFactory(factory);
    }

    public void setMacaddress(String macaddress) {
        getDbDevice().setMacaddress(macaddress);
    }

    public void setName(String name) {
        getDbDevice().setName(name);
    }

    public void setSerialno(String serialno) {
        getDbDevice().setSerialno(serialno);
    }

    public void setStates(DeviceStatus states) {

        if (states==null){
            states=DeviceStatus.ONLINE;
        }
        getDbDevice().setStates(states.getCode());

    }

    public void setSubsyscode(String subsyscode) {
        getDbDevice().setSubsyscode(subsyscode);
    }


    public String getAreaid() {
        return getDbDevice().getAreaid();
    }


    public void setAreaid(String areaid) {
        getDbDevice().setAreaid(areaid);
    }


    public String getPlaceid() {
        return getDbDevice().getPlaceid();
    }


    public void setPlaceid(String placeid) {
        getDbDevice().setPlaceid(placeid);
    }

    @JSONField(serialize = false)
    
    public List<DeviceEndPoint> getDeviceEndPoints() {

        List<DeviceEndPoint> epList = new ArrayList<DeviceEndPoint>();
        try {
            epList = AppEngine.getEngine(systemCode).getAllEndPoints(this.getDeviceid());
        } catch (HomeException e) {
            e.printStackTrace();
        }

        return epList;
    }

    @JSONField(serialize = false)
    
    public Sensortype getSensortype() {
        Sensortype sensortype = null;
        try {
            sensortype = AppEngine.getEngine(systemCode).getSensorTypesByNo(getDbDevice().getDevicetype());
        } catch (HomeException e) {
            e.printStackTrace();
        }

        return sensortype;

    }

    @Override
    public Long getLastlogintime() {
        return getDbDevice().getLastlogintime();
    }

    @Override
    public void setLastlogintime(Long lastlogintime) {
        getDbDevice().setLastlogintime(lastlogintime);
    }

    @JSONField(serialize = false)
    
    public List<ZNode> getAllZNodes() {
        List<ZNode> znodeList = new ArrayList<ZNode>();

        if (!this.getDeviceid().equals(this.getBindingaccount())) {
            List<DeviceEndPoint> endPoints = this.getDeviceEndPoints();
            for (DeviceEndPoint endPoint : endPoints) {
                List<ZNode> nodes = endPoint.getAllZNodes();
                znodeList.addAll(nodes);
            }
        } else {
            try {
                znodeList = AppEngine.getEngine(systemCode).getAllZNodeByDeviceId(this.getDeviceid());
            } catch (HomeException e) {
                e.printStackTrace();
            }
        }
        return znodeList;
    }

    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if ((object != null) && ((object instanceof Device))) {
            return getDeviceid().equals(((Device) object).getDeviceid());
        }
        return false;
    }

    @JSONField(serialize = false)
    
    public EIDevice getDbDevice() {
        EIDevice device = null;
        try {
            device = GWEngine.getDefaultEngine().getDeviceById(this.deviceId);
        } catch (HomeException e) {
            e.printStackTrace();
        }
        return device;
    }


    @JSONField(serialize = false)
    
    public List<Device> getSub() {

        if (this.getChildDevices().size() > 0) {
            return this.getChildDevices();
        } else {
            return null;
        }

    }

    @JSONField(serialize = false)
    public List<Device> getChildDevices() {

        List<Device> devices = new ArrayList<Device>();
        if (getDbDevice().isRoot()) {
            Set<String> deviceIds = getDbDevice().getChildDeviceIds();
            for (String deviceId : deviceIds) {
                try {
                    devices.add(AppEngine.getEngine(systemCode).getDeviceById(deviceId));
                } catch (HomeException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        return devices;
    }

    @JSONField(serialize = false)
    
    public Device getRootDevice() {
        Device rootDevice = null;
        if (this.getBindingaccount().equals(this.getDeviceid())) {
            rootDevice = this;
        } else {
            String rootDeviceId = this.getDbDevice().getRootDevice().getDeviceid();
            try {
                rootDevice = AppEngine.getEngine(systemCode).getDeviceById(rootDeviceId);
            } catch (HomeException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        return rootDevice;

    }


    public Set<String> getChildDeviceIds() {
        return new LinkedHashSet<String>(getDbDevice().getChildDeviceIds());
    }


    public Set<String> getDeviceEndPointIds() {
        return new LinkedHashSet<String>(getDbDevice().getDeviceEndPointIds());
    }


    public Set<String> getAllZNodeIds() {
        Set<String> nodeIds = new LinkedHashSet<String>();
        List<ZNode> znodes = this.getAllZNodes();
        for (ZNode node : znodes) {
            nodeIds.add(node.getZnodeid());
        }

        return nodeIds;
    }


    public void setAllZNodeIds(Set<String> znodeIds) {

    }


    public void setDeviceEndPointIds(Set<String> endpointIds) {

    }


    public void setChildDeviceIds(Set<String> childDeviceIds) {

    }

}
